1 00:00:00,490 --> 00:00:01,180 Welcome. 2 00:00:01,180 --> 00:00:01,870 In this lecture. 3 00:00:01,870 --> 00:00:06,140 We're going to take a look at how to create a simple vehicle with suspension. 4 00:00:06,160 --> 00:00:10,810 I've attached this model to the lecture, so you will want to go ahead and grab it so you can follow 5 00:00:10,810 --> 00:00:13,420 along with me inside of this vehicle. 6 00:00:13,420 --> 00:00:15,340 We have a couple of things. 7 00:00:15,340 --> 00:00:20,920 We have a vehicle seat and inside of this vehicle seat we have some attachments. 8 00:00:20,920 --> 00:00:26,650 So there's an attachment below the vehicle seat and there's an attachment above the vehicle seat. 9 00:00:26,650 --> 00:00:30,970 And these are going to be for when our player exits the seat of the vehicle. 10 00:00:30,970 --> 00:00:36,910 We're either going to teleport them to this top one or this bottom one, depending on if the car is 11 00:00:36,910 --> 00:00:37,810 flipped or not. 12 00:00:37,810 --> 00:00:40,480 And the vehicle has a proximity prompt in it as well. 13 00:00:40,480 --> 00:00:45,100 So we can walk up to the car, activate the proximity prompt and drive the vehicle. 14 00:00:45,190 --> 00:00:51,160 We have a model here and inside this is just for all of the tires and each tire has an attachment inside 15 00:00:51,160 --> 00:00:51,640 of it. 16 00:00:51,640 --> 00:00:57,400 And this attachment is just at the position that's in the directly in the center of our tire. 17 00:00:58,420 --> 00:01:02,450 And then inside of our body we have an additional five attachments. 18 00:01:02,470 --> 00:01:07,270 These attachments here are going to be for each of the tires because we're going to be connecting some 19 00:01:07,270 --> 00:01:12,940 constraints of the attachments and the tires to these attachments here, which include a spring and 20 00:01:12,940 --> 00:01:15,880 a cylindrical constraint, which we'll use in a little bit. 21 00:01:16,180 --> 00:01:20,170 And then I have one more attachment here inside of the engine compartment. 22 00:01:20,170 --> 00:01:25,870 And this just holds some audio, some sound instances that will play when the car starts up and when 23 00:01:25,870 --> 00:01:26,770 it's driving. 24 00:01:27,130 --> 00:01:29,110 We're just going to pick a random tire. 25 00:01:29,110 --> 00:01:31,540 So I'm going to pick this tire right here. 26 00:01:32,140 --> 00:01:38,230 And with this tire, we're going to create something called a cylindrical constraint right here. 27 00:01:38,730 --> 00:01:41,820 And this constraint requires two attachments. 28 00:01:41,820 --> 00:01:47,850 So the first attachment we're going to do is the one that corresponds to this front left tire, which 29 00:01:47,850 --> 00:01:51,330 is the attachment for the front left tire right here. 30 00:01:51,600 --> 00:01:55,140 And then the second attachment is going to be the one inside of our tire. 31 00:01:55,530 --> 00:02:01,830 So we've created a constraint between this attachment and this attachment. 32 00:02:02,810 --> 00:02:10,370 And what this constraint allows you to do is it allows this part to move in the direction that is defined 33 00:02:10,370 --> 00:02:14,030 here, which I believe will be forwards and backwards. 34 00:02:14,030 --> 00:02:20,360 So this constraint allows this tire to only move forwards and backwards an infinite amount of distance. 35 00:02:20,390 --> 00:02:25,310 Of course, we're going to be using this cylindrical constraint to allow the tire to move only up and 36 00:02:25,310 --> 00:02:29,060 down a bit to help with the suspension and to limit its movement. 37 00:02:30,260 --> 00:02:32,000 So I'll just show you how this works real quick. 38 00:02:32,000 --> 00:02:37,580 But before I do that, I'm going to anchor the body of the car so my car stays up in the air and we'll 39 00:02:37,580 --> 00:02:38,690 hit play here. 40 00:02:42,790 --> 00:02:44,830 And there is our cylindrical constraint. 41 00:02:44,830 --> 00:02:49,480 As you can see, it has moved to the position that was in the attachment for our car. 42 00:02:49,480 --> 00:02:54,730 But since we're going to be adding suspension later and the tire is going to be moving up and down, 43 00:02:54,730 --> 00:02:57,220 it won't be teleported in a strange position. 44 00:02:57,220 --> 00:03:04,660 But as you can see, if I touch the tire, you see it only moves forward and backwards infinitely in 45 00:03:04,660 --> 00:03:08,230 these directions that are for the cylindrical constraint. 46 00:03:08,650 --> 00:03:10,570 I can't move it this way. 47 00:03:10,570 --> 00:03:11,590 I can't move it up or down. 48 00:03:11,590 --> 00:03:14,050 It can only move forwards and backwards. 49 00:03:14,320 --> 00:03:19,330 So in order to allow our tire to go up and down instead of forwards and backwards, what we'll need 50 00:03:19,330 --> 00:03:25,030 to do is to rotate an attachment that is inside of the body. 51 00:03:25,030 --> 00:03:31,930 So this attachment for our front tire here, we need to rotate this attachment by 90 degrees on the 52 00:03:31,960 --> 00:03:33,370 Z axis, right? 53 00:03:33,370 --> 00:03:39,100 So if we go to the orientation of the C frame, if we rotate it by 90 degrees, we should now allow 54 00:03:39,100 --> 00:03:41,010 our tire to go up and down. 55 00:03:41,020 --> 00:03:43,100 So if we go and play here. 56 00:03:43,800 --> 00:03:48,660 You see now our tire has been rotated, but it only goes up and down now. 57 00:03:48,870 --> 00:03:55,050 Now, the issue here is we need to rotate this tire itself to be vertical instead of horizontal like 58 00:03:55,050 --> 00:03:57,510 this because a car's tires aren't horizontal. 59 00:03:57,750 --> 00:03:59,940 Thankfully, that's also easy to do. 60 00:03:59,970 --> 00:04:04,470 What we need to do is we need to go to the cylindrical constraint. 61 00:04:04,470 --> 00:04:11,370 And inside of here there's an inclination angle property and we're just going to enter in 90 or representing 62 00:04:11,370 --> 00:04:12,330 90 degrees. 63 00:04:12,360 --> 00:04:14,760 And this should rotate the tire for us. 64 00:04:17,320 --> 00:04:20,440 Now, if we play test here, you see now our tire. 65 00:04:21,890 --> 00:04:22,860 Is vertical. 66 00:04:22,880 --> 00:04:24,320 Now there's another issue. 67 00:04:25,050 --> 00:04:27,180 Our tire is facing inwards. 68 00:04:27,180 --> 00:04:31,170 We don't want it to face inwards because this is the inside part of the tire and that's the outside 69 00:04:31,170 --> 00:04:31,770 part of the tire. 70 00:04:31,770 --> 00:04:34,110 We want this part to be facing this way. 71 00:04:34,470 --> 00:04:41,280 So again, what we could do is we can go to the attachment that is in the tire and we're going to rotate 72 00:04:41,280 --> 00:04:42,720 it by 180 degrees. 73 00:04:42,720 --> 00:04:44,670 So we're just going to flip it all around. 74 00:04:44,670 --> 00:04:46,740 And again, we can do that on the Z axis. 75 00:04:46,740 --> 00:04:51,110 We're just going to flip the tire entirely like that. 76 00:04:51,120 --> 00:04:53,820 So as you can see, our attachment has been flipped. 77 00:04:54,000 --> 00:04:56,310 And if we go and play, test it again. 78 00:04:59,110 --> 00:05:02,440 As you can see, our tire is now facing in the proper direction. 79 00:05:02,890 --> 00:05:07,570 Now, the next thing we need to do for our tire is we need to constrain its movements, because right 80 00:05:07,570 --> 00:05:12,790 now it's going to go an infinite direction, upwards or downwards because there's no limit set on this 81 00:05:12,790 --> 00:05:14,200 cylindrical constraint. 82 00:05:15,070 --> 00:05:21,130 So in order to set a limit on our cylindrical constraint, there is a property in here and this property 83 00:05:21,130 --> 00:05:22,450 is limits enabled. 84 00:05:22,450 --> 00:05:29,680 So when I enable this property, you should see this bar appear and it's telling us what the limit is 85 00:05:29,680 --> 00:05:31,500 going to be for our tire. 86 00:05:31,510 --> 00:05:34,480 So we have a lower limit and an upper limit right now. 87 00:05:34,480 --> 00:05:36,730 We don't want it to be at an upper limit of five. 88 00:05:36,730 --> 00:05:40,450 So what I'm going to do is I'm going to set the lower limit. 89 00:05:40,450 --> 00:05:48,370 I'm going to set this to -1.5, and that's -1.5 studs from this attachment. 90 00:05:48,490 --> 00:05:54,640 And then the upper limit, I'm going to set to be -0.3. 91 00:05:54,640 --> 00:05:58,300 So -0.3 studs from this attachment will be right here. 92 00:05:58,330 --> 00:06:05,380 Now, the reason I'm doing this is because I don't want the tire to move above this attachment because 93 00:06:05,380 --> 00:06:09,070 that means the attachment inside of the tire would go above this attachment. 94 00:06:09,070 --> 00:06:13,060 And when that happens, well, we're going to be adding a spring. 95 00:06:13,510 --> 00:06:18,950 Once this attachment goes above this attachment, the spring is going to flip around and the spring 96 00:06:18,950 --> 00:06:20,810 is going to apply force this way. 97 00:06:20,810 --> 00:06:24,950 But we only want the spring to apply force in this direction, right? 98 00:06:25,250 --> 00:06:29,330 So we have to constrain how far up we can move the tire. 99 00:06:29,360 --> 00:06:31,490 We don't want it to go above this attachment. 100 00:06:31,760 --> 00:06:37,190 And here I've allowed the tire to go down a little bit more as well, just, you know, to have a tire 101 00:06:37,190 --> 00:06:38,900 hang out when we're in the air. 102 00:06:39,440 --> 00:06:45,050 Now, another thing I will note for the tires is I've enabled a property in here called Custom Physical 103 00:06:45,050 --> 00:06:46,040 Properties. 104 00:06:46,250 --> 00:06:49,910 And in here it allows me to change several things about this part. 105 00:06:49,940 --> 00:06:53,180 It allows me to change the density or how much mass the part has. 106 00:06:53,210 --> 00:06:58,400 It allows me to change the elasticity, which just kind of determines how much the part will bounce 107 00:06:58,400 --> 00:06:59,960 around when it hits something. 108 00:07:00,020 --> 00:07:02,300 It allows me to change the friction. 109 00:07:02,300 --> 00:07:04,760 And of course we want to have a high friction. 110 00:07:04,850 --> 00:07:09,770 I've increased the density of the tire to give it some more mass, and I've also increased the friction 111 00:07:09,770 --> 00:07:11,750 and reduce the elasticity. 112 00:07:11,840 --> 00:07:16,580 So if you ever wanted your car to drift more, then of course you'd want to reduce the friction that 113 00:07:16,580 --> 00:07:17,210 I've set here. 114 00:07:17,210 --> 00:07:19,790 But I've set it to 1.2 for all the tires. 115 00:07:19,850 --> 00:07:24,260 Now the last thing we need to do for our tires, we need to create a spring attachment. 116 00:07:24,930 --> 00:07:26,430 Or a spring constraint. 117 00:07:27,600 --> 00:07:30,750 And inside of the spring constraint, again, two attachments. 118 00:07:30,750 --> 00:07:36,270 We're going to first select the one that is in the car, which is going to be attachment for our front 119 00:07:36,300 --> 00:07:39,930 tire and the left, and then the attachment that is inside of our tire. 120 00:07:40,170 --> 00:07:42,840 And as you can see, it has created this spring constraint. 121 00:07:42,840 --> 00:07:48,510 And like I was talking about earlier, we don't want this part to go above this part because that means 122 00:07:48,510 --> 00:07:53,340 our spring right here is going to flip and it's going to be exerting force in the wrong direction. 123 00:07:53,340 --> 00:07:54,300 We don't want to do that. 124 00:07:55,420 --> 00:07:59,170 So in our spring constraint, we need to change some properties. 125 00:07:59,170 --> 00:08:00,580 We see we have some right here. 126 00:08:00,580 --> 00:08:03,640 We have one called dampening or damping. 127 00:08:03,640 --> 00:08:11,740 And damping is used to kind of reduce or dampen and soften the force that is applied by the spring. 128 00:08:12,370 --> 00:08:20,030 So typically a spring likes to go back to its resting state or its free length, which is one stud long. 129 00:08:20,050 --> 00:08:27,040 So if I stretch the spring beyond one stud or I compress it below one stud, it's going to exert a force 130 00:08:27,040 --> 00:08:28,450 to try to get back to that. 131 00:08:28,450 --> 00:08:32,740 Free length and dampening allows us to soften that force out. 132 00:08:32,740 --> 00:08:35,920 So instead of it being super springy, it's more gentle. 133 00:08:35,920 --> 00:08:37,330 It kind of goes out slower. 134 00:08:38,130 --> 00:08:43,080 So for this vehicle, I'm going to set the damping to be around 400. 135 00:08:43,380 --> 00:08:48,300 Now for the free length, I want the spring to have a bit of room to stretch out. 136 00:08:48,300 --> 00:08:54,900 So I would say the resting length of our spring should be probably around 2.5 studs, which you see 137 00:08:54,900 --> 00:08:57,540 indicated by these blue arrows. 138 00:08:57,540 --> 00:09:00,510 So our tire will push the car up a little bit. 139 00:09:01,880 --> 00:09:03,410 Now for the stiffness. 140 00:09:03,410 --> 00:09:08,690 This is going to be the amount of force that the spring is going to exert to try to get back to its 141 00:09:08,690 --> 00:09:09,590 free length. 142 00:09:09,980 --> 00:09:12,390 And these numbers are kind of arbitrary. 143 00:09:12,410 --> 00:09:15,710 They're just kind of, you know, represent a higher number, more force. 144 00:09:15,710 --> 00:09:20,980 But for this vehicle, a stiffness of around 5500 works pretty good. 145 00:09:21,140 --> 00:09:25,520 Now, if we actually go and play test the game, you'll see the spring is going to stretch out to its 146 00:09:25,520 --> 00:09:26,390 free length. 147 00:09:27,140 --> 00:09:29,870 And as you can see, our tire is hanging here. 148 00:09:31,080 --> 00:09:35,700 Now, if the car falls down and compresses on the spring, the spring is going to and exert a force 149 00:09:35,700 --> 00:09:40,600 back to resist the gravity or weight of the car, which is going to push the car up. 150 00:09:40,620 --> 00:09:44,550 If we had a stiffness that was too weak, then the spring would get compressed too much. 151 00:09:44,550 --> 00:09:48,270 So that's why I thought 5500 was pretty good for this vehicle. 152 00:09:48,270 --> 00:09:51,480 But of course you can go ahead and tweak it to however you like. 153 00:09:52,170 --> 00:09:56,340 But now that we have all of this set up for this tire, there's one more thing we need to do. 154 00:09:56,930 --> 00:10:00,740 And we need to stop this tire from colliding with the body. 155 00:10:00,950 --> 00:10:05,720 Since this body is a mesh, the collision in the body is not exactly perfect. 156 00:10:05,720 --> 00:10:10,640 So this tire is going to be colliding with the body when it tries to go up and down with the spring. 157 00:10:10,760 --> 00:10:16,460 So an easy way to fix this would not to be using collision groups, but there's a constraint we can 158 00:10:16,460 --> 00:10:21,680 use called no collision constraint, which allows you to select two parts for them not to collide with 159 00:10:21,680 --> 00:10:22,320 each other. 160 00:10:22,340 --> 00:10:28,850 So we can select the tire and we don't want the tire to collide with the body just like that. 161 00:10:29,690 --> 00:10:34,510 Now that we've got the setup for this first hire, we need to do it for the rest of our tires. 162 00:10:34,520 --> 00:10:41,300 So what I'm going to do is I'm going to copy all of these constraints and I'm going to paste it into 163 00:10:41,300 --> 00:10:42,170 this one. 164 00:10:43,520 --> 00:10:46,670 And what we're going to have to do is change the attachments in here. 165 00:10:46,670 --> 00:10:52,790 So for this attachment, we need to do the front right tire and the attachment is going to be the one 166 00:10:52,790 --> 00:10:54,260 inside of this tire. 167 00:10:55,280 --> 00:10:56,720 For our no collusion constraint. 168 00:10:56,720 --> 00:11:02,030 We need to select the front right tire and for the spring we need to do the same thing. 169 00:11:02,150 --> 00:11:07,010 This is the front right tire attached to the attachment inside of the tire. 170 00:11:08,960 --> 00:11:15,830 Now, we also need to make sure that we rotate the same thing here inside of this attachment. 171 00:11:15,830 --> 00:11:18,410 So we did 180 degrees for this one. 172 00:11:18,410 --> 00:11:22,400 We also need to do 180 degrees for this one as well. 173 00:11:23,400 --> 00:11:30,090 And then we also need to rotate this attachment in here, which was by 90 degrees. 174 00:11:30,920 --> 00:11:31,250 Again. 175 00:11:31,250 --> 00:11:34,130 We'll do the same thing for the rear left tire. 176 00:11:34,870 --> 00:11:37,990 We're going to select rear tire. 177 00:11:38,650 --> 00:11:47,830 The attachment inside of the rear left tire for the collision again, rear left tire and then rear left 178 00:11:47,860 --> 00:11:49,990 tire and the attachment inside of the tire. 179 00:11:51,090 --> 00:11:51,660 Once more. 180 00:11:51,660 --> 00:11:57,990 For this one, we'll just select for the rear right tire attachment in here. 181 00:11:59,070 --> 00:12:03,750 Pick this tire and then again, the attachment for the rear. 182 00:12:04,910 --> 00:12:06,650 And for this attachment. 183 00:12:07,070 --> 00:12:07,900 Perfect. 184 00:12:07,910 --> 00:12:10,490 So now we should have all of our tires set up. 185 00:12:10,490 --> 00:12:15,800 And in order to make sure we confirm this is working, we can go and play a test real quick. 186 00:12:16,680 --> 00:12:17,250 All right. 187 00:12:17,250 --> 00:12:20,490 So you should be noticing a couple issues here. 188 00:12:22,860 --> 00:12:28,320 These tires are looking a little wonky and we'll go ahead and have to fix that real quick. 189 00:12:29,610 --> 00:12:33,150 Because we forgot to rotate these attachments. 190 00:12:34,010 --> 00:12:39,320 So again, you have to rotate it by 180 degrees on these two attachments. 191 00:12:40,220 --> 00:12:41,960 And then for the attachments and the tire. 192 00:12:41,960 --> 00:12:43,880 Remember, we have to do 90 degrees. 193 00:12:46,710 --> 00:12:48,270 Now if we play test again. 194 00:12:48,940 --> 00:12:54,880 You should notice one more thing and you will see that these tires here are rotated correctly, but 195 00:12:54,880 --> 00:12:56,170 these tires are not. 196 00:12:56,170 --> 00:13:01,990 And that's because I had to copy and paste one of these tires and use them for the rest, which means 197 00:13:01,990 --> 00:13:03,520 I had to rotate one of them. 198 00:13:03,520 --> 00:13:05,500 So they're being flipped in the wrong direction. 199 00:13:05,500 --> 00:13:10,390 And an easy way to fix that would to be to just select these two tires. 200 00:13:11,490 --> 00:13:13,710 And for the attachments in them. 201 00:13:13,710 --> 00:13:18,480 We just need to undo that 180 degree rotation that flipped them around. 202 00:13:19,260 --> 00:13:21,480 So one more time if we play test. 203 00:13:22,190 --> 00:13:25,730 You will see that all of our tires are facing the correct direction. 204 00:13:25,940 --> 00:13:31,340 And that also means if I go to an anchor, the body of the car just like so. 205 00:13:34,750 --> 00:13:38,380 You will now see that our tires are holding up the car. 206 00:13:39,100 --> 00:13:40,750 But it's been a little weird. 207 00:13:40,780 --> 00:13:45,280 I think there's some problems with the physics because I'm recording and it's trying to calculate physics 208 00:13:45,310 --> 00:13:48,490 at the same time, but I think it's figured itself out. 209 00:13:48,490 --> 00:13:50,860 But as you can see now, we have suspension on our vehicle. 210 00:13:50,860 --> 00:13:54,430 And if I jump on the vehicle, you can see the suspension working there. 211 00:13:55,660 --> 00:13:59,830 So I'm hopping on my vehicle and you can see our car has some nice suspension. 212 00:14:00,730 --> 00:14:05,560 Now we need to do another thing inside of all of our cylindrical constraints. 213 00:14:05,560 --> 00:14:07,060 I'm going to select all of them. 214 00:14:07,180 --> 00:14:12,400 We have to change something in here called angular actuator type. 215 00:14:12,700 --> 00:14:17,310 And this is going to allow us to rotate the tires and allow the car to drive. 216 00:14:17,320 --> 00:14:20,410 So that means we need to set this actuator type to motor. 217 00:14:20,410 --> 00:14:25,360 And when you do this, you should see all of these blue arrows show up and it's telling us the direction 218 00:14:25,360 --> 00:14:30,100 that the tires will rotate when we apply a positive force on the tire. 219 00:14:31,540 --> 00:14:35,260 So and here we get a few more properties, we get an angular velocity. 220 00:14:35,350 --> 00:14:40,780 The velocity of the rotation of our tire and then the torque for the motor that's rotating our tire. 221 00:14:40,810 --> 00:14:42,520 Of course we're going to need some torque. 222 00:14:42,520 --> 00:14:45,060 If we don't, it's going to take forever to rotate the tires. 223 00:14:45,070 --> 00:14:50,800 So as an example, I'm going to set this to 4000 and I'm just going to run the server. 224 00:14:53,020 --> 00:14:55,000 And inside of our tires. 225 00:14:55,180 --> 00:14:58,480 What I'll do for each of these cylindrical constraints. 226 00:15:00,050 --> 00:15:02,540 Is that I'm going to apply some force here. 227 00:15:02,540 --> 00:15:06,050 So I'm going to increase the angular velocity to ten. 228 00:15:07,000 --> 00:15:11,020 And as you can see, all of the tires on our car start rotating. 229 00:15:11,770 --> 00:15:15,310 But if I reduce the torque to something, let's say ten. 230 00:15:16,440 --> 00:15:20,430 And then I set the angular velocity to zero. 231 00:15:20,460 --> 00:15:27,090 You'll see that the tires take a long time to stop because we have very little torque. 232 00:15:28,900 --> 00:15:34,750 But now that they've stopped, if I keep the torque low actually at like ten and then I try to apply 233 00:15:34,750 --> 00:15:37,330 some velocity that's hires like 100. 234 00:15:38,030 --> 00:15:41,450 You see, it takes a very long time for them to go. 235 00:15:41,450 --> 00:15:43,280 And that's because we don't have much talk here. 236 00:15:44,570 --> 00:15:53,150 But if I set the talk to something like 5000, we're able to speed up these tires a lot faster, basically 237 00:15:53,150 --> 00:15:54,890 instantly, because we have more torque. 238 00:15:55,370 --> 00:16:00,520 And in order to have our vehicle drive around and pull itself up mountains, we need more torque. 239 00:16:00,530 --> 00:16:06,080 So for this vehicle in particular, I found that a torque of around 7000 should work just fine. 240 00:16:07,980 --> 00:16:13,470 So I'm going to stop the test and I'm going to reset these talks back to zero, because now is the time 241 00:16:13,470 --> 00:16:15,510 we can start scripting our car. 242 00:16:16,870 --> 00:16:21,140 What I'm going to do is I'm going to create a new script inside of the vehicle seat. 243 00:16:21,800 --> 00:16:28,990 We can just name this script, something like vehicle script and the script. 244 00:16:29,000 --> 00:16:30,710 We're going to need a few things. 245 00:16:30,710 --> 00:16:32,630 We're going to need some services. 246 00:16:32,780 --> 00:16:36,170 So we'll just need between service in this case. 247 00:16:38,780 --> 00:16:41,060 And then we'll need some variables. 248 00:16:41,330 --> 00:16:44,330 One, we need to store the car, which is easy. 249 00:16:44,330 --> 00:16:50,060 It's just going to be script dot parent, dot parent. 250 00:16:50,330 --> 00:16:51,410 Actually, you know what? 251 00:16:51,410 --> 00:16:53,720 I'll just put the script directly in the car instead. 252 00:16:54,290 --> 00:16:56,150 So that way it's just script dot parent. 253 00:16:56,150 --> 00:16:57,350 We'll just do that instead. 254 00:16:58,370 --> 00:17:01,700 Next, we need to reference the model for the tires. 255 00:17:01,700 --> 00:17:04,430 So that'll just be car tires. 256 00:17:06,180 --> 00:17:12,450 And then since we want the car to drive, we're going to need to reference all of the cylindrical constraints 257 00:17:12,450 --> 00:17:17,460 inside of each tire so we can apply a velocity in here to get the car moving. 258 00:17:17,760 --> 00:17:19,440 So we'll just reference each one. 259 00:17:19,440 --> 00:17:22,890 We'll do cyl cylindrical. 260 00:17:24,780 --> 00:17:28,020 And we'll do front left equal to tires. 261 00:17:28,020 --> 00:17:30,930 Dot front l dot cylindrical constraint. 262 00:17:32,250 --> 00:17:36,090 Do the same thing for the front, right? 263 00:17:41,650 --> 00:17:43,810 We'll do one for the rear as well. 264 00:17:43,810 --> 00:17:47,410 So we'll do rear left equal two tires. 265 00:17:47,770 --> 00:17:49,440 Rear left. 266 00:17:49,870 --> 00:17:54,340 Cylindrical constraint and then cylindrical. 267 00:17:54,940 --> 00:17:55,630 Oops. 268 00:18:04,840 --> 00:18:05,530 There we go. 269 00:18:05,740 --> 00:18:08,280 Cylindrical rear right. 270 00:18:08,290 --> 00:18:13,150 Equal tires dot rear dot, cylindrical constraint. 271 00:18:14,310 --> 00:18:18,900 Then I'll create a reference to the seat in the car, which is just car dot. 272 00:18:18,900 --> 00:18:20,310 Vehicle seat. 273 00:18:22,060 --> 00:18:28,510 I'll create a reference to the prompt in the seat that's equal to seat dot proximity prompt. 274 00:18:28,660 --> 00:18:32,920 And then I'm going to keep track of who is currently sitting in the seat. 275 00:18:33,010 --> 00:18:34,990 We'll just call it current occupant. 276 00:18:35,080 --> 00:18:36,130 Set it to nil. 277 00:18:37,520 --> 00:18:40,640 And then we'll need to reference the sounds that are in the vehicle. 278 00:18:40,640 --> 00:18:43,400 So we'll do one for the idle sound. 279 00:18:43,430 --> 00:18:45,380 It's going to be in the car. 280 00:18:45,470 --> 00:18:51,440 We get the body of the car and there's an attachment in there called engine sounds and we'll get the 281 00:18:51,440 --> 00:18:55,970 car idle sound and then we'll have the start sound as well. 282 00:19:00,630 --> 00:19:01,140 Okay. 283 00:19:01,350 --> 00:19:03,840 And then we'll need some constants. 284 00:19:04,340 --> 00:19:08,130 And these constants are going to define some limitations on our vehicle. 285 00:19:08,490 --> 00:19:13,750 So the first limitation we need to define is the max angular velocity. 286 00:19:13,770 --> 00:19:18,520 So what's the max velocity that we want to apply for the tires? 287 00:19:18,540 --> 00:19:24,570 And we can do this by checking to see what the max speed property is here in our seat. 288 00:19:25,020 --> 00:19:29,780 And inside I've set the max speed to be 65 or 65, I believe Studs. 289 00:19:29,790 --> 00:19:32,610 I think it's 65 studs per second, if I'm correct. 290 00:19:32,910 --> 00:19:36,770 And I also set the torque that we'll use for the vehicle as well. 291 00:19:36,780 --> 00:19:43,290 But in order to calculate the max angular velocity, we need to get the seats dot max speed. 292 00:19:44,110 --> 00:19:51,610 And we need to divide it by the radius of one of the tires so that way we can get the max angular velocity. 293 00:19:52,320 --> 00:19:54,930 So it's easy to get one of the radius of the tires. 294 00:19:54,930 --> 00:19:56,610 We just need to grab one. 295 00:19:56,610 --> 00:19:58,340 We'll just do tires, Dot. 296 00:19:58,530 --> 00:19:59,940 Let's just do front left. 297 00:20:00,210 --> 00:20:10,080 We'll get the size of it in the y axis and that's going to be the total width of our tire. 298 00:20:10,080 --> 00:20:12,600 But we want the radius, which is half of the total width. 299 00:20:12,600 --> 00:20:17,310 So we'll just divide it by two and we'll get our max angular velocity to make sure that we don't go 300 00:20:17,310 --> 00:20:18,720 above this max speed. 301 00:20:20,470 --> 00:20:24,370 Next, we need to set a constant for defining. 302 00:20:25,170 --> 00:20:28,500 How far we want the tires on the front to rotate when we're steering. 303 00:20:28,500 --> 00:20:34,590 So the max rotation will have is 35 degrees, so the tires will rotate 35 degrees to the left or to 304 00:20:34,590 --> 00:20:36,240 the right to turn either left or right. 305 00:20:37,740 --> 00:20:42,420 And then we needed to define a constant for our ideal sound. 306 00:20:42,690 --> 00:20:47,910 So my plan is, is that when we're driving the car, when the car goes faster and faster, we're going 307 00:20:47,910 --> 00:20:54,330 to set the playback speed of our car idle sound to be higher and higher, which makes it sound like, 308 00:20:54,330 --> 00:20:56,190 you know, the car is driving faster and faster. 309 00:20:56,190 --> 00:20:57,530 It's having higher RPM. 310 00:20:57,540 --> 00:21:01,950 But when the car is not moving, we still want the idle sound to be playing, which is why we need a 311 00:21:01,950 --> 00:21:04,560 minimum playback sound for when we're idling. 312 00:21:05,880 --> 00:21:09,390 And that's going to be a playback speed of, let's say, 0.6. 313 00:21:10,810 --> 00:21:14,440 One more constant is going to be called rotation duration. 314 00:21:14,470 --> 00:21:15,430 What is this for? 315 00:21:15,790 --> 00:21:21,460 So when we turn the steering wheel to go left or right, how long do we want it to take for the tires 316 00:21:21,460 --> 00:21:23,260 to rotate either left or right? 317 00:21:23,890 --> 00:21:28,330 And I found that about 0.4 seconds would be good for that. 318 00:21:29,180 --> 00:21:32,540 Next thing we need to do is define one function. 319 00:21:32,660 --> 00:21:38,550 And this function is going to be for updating the playback speed of our idle sound. 320 00:21:38,570 --> 00:21:40,130 I'll just call it update audio. 321 00:21:42,060 --> 00:21:45,210 And then we'll need to listen to some events. 322 00:21:46,000 --> 00:21:51,550 Well, first off, we need to listen to when our prompt gets triggered because a player wants to enter 323 00:21:51,550 --> 00:21:52,450 the vehicle. 324 00:21:53,110 --> 00:21:57,400 We need to listen to when a property in the seat changes. 325 00:21:57,400 --> 00:21:58,930 That's called occupant. 326 00:21:59,140 --> 00:22:04,570 So the vehicle seat has a property in here that tells us who the occupant of our seat is. 327 00:22:04,570 --> 00:22:05,830 Where is that at? 328 00:22:06,530 --> 00:22:07,300 Here it is right here. 329 00:22:07,310 --> 00:22:13,340 Occupant So whenever a player goes into the seat, it'll tell us the humanoid of that player so we can 330 00:22:13,340 --> 00:22:14,360 get the occupant. 331 00:22:14,720 --> 00:22:17,270 So we'll get property change signal. 332 00:22:18,100 --> 00:22:19,480 That's going to be occupant. 333 00:22:20,570 --> 00:22:26,270 And when that property changes, we are going to do some stuff in there. 334 00:22:26,870 --> 00:22:31,640 We also need to listen to when a property in the seat called steer changes. 335 00:22:31,640 --> 00:22:34,730 So get property change signal steer. 336 00:22:36,390 --> 00:22:42,870 And what this does is that if we turn left, the steer property turns to the number one. 337 00:22:42,900 --> 00:22:45,370 If we steer to the right, it turns to negative one. 338 00:22:45,370 --> 00:22:47,370 And if we don't steer at all, it's zero. 339 00:22:47,520 --> 00:22:49,620 So we need to pay attention to that. 340 00:22:49,830 --> 00:22:55,470 And we also need to pay attention to when the player presses on the gas to either go backwards or forwards 341 00:22:55,620 --> 00:22:58,920 so we can do seat jet property change signal. 342 00:22:58,920 --> 00:23:00,990 And this property is called throttle. 343 00:23:02,480 --> 00:23:06,260 So if we go forwards, it's a positive number of one. 344 00:23:06,260 --> 00:23:08,480 If we go backwards, it's negative one. 345 00:23:08,480 --> 00:23:10,340 If we don't move at all, it's zero. 346 00:23:10,490 --> 00:23:12,590 So we'll connect a function to that as well. 347 00:23:14,390 --> 00:23:15,800 And that's all we need to do. 348 00:23:15,920 --> 00:23:21,980 So what we can first fill out is the event for when our prompt gets triggered by a player. 349 00:23:22,160 --> 00:23:28,280 So what we want to do is we first want to check is if there's already someone sitting in our vehicle. 350 00:23:28,310 --> 00:23:33,060 So if our seat already has an occupant, then we'll just return, right? 351 00:23:33,080 --> 00:23:35,060 You can't have two drivers of a car. 352 00:23:35,850 --> 00:23:41,820 The next thing we want to check for is if the player who activated this prompt has a character model. 353 00:23:41,850 --> 00:23:46,410 Because if they don't, well, we don't want to put them in the seat. 354 00:23:46,410 --> 00:23:52,680 And exploiters can also fire prompts, even if they don't have a character or anything, they can just 355 00:23:52,680 --> 00:23:54,190 fire them whenever they want. 356 00:23:54,210 --> 00:23:56,160 So we got to make sure we stop that. 357 00:23:56,310 --> 00:24:01,980 So if this player doesn't have a character, so if not player dot character, then we'll just return 358 00:24:01,980 --> 00:24:02,550 as well. 359 00:24:04,580 --> 00:24:09,810 Otherwise we can use a function on our C and it's called sit. 360 00:24:09,830 --> 00:24:15,110 And what we do is we pass a humanoid to this function and it forces them to sit in the car seat. 361 00:24:15,110 --> 00:24:18,620 In this case, that's going to be the player's character humanoid. 362 00:24:19,400 --> 00:24:23,750 So now we are forcing the player to sit in the seat and that's all we need to do there. 363 00:24:24,380 --> 00:24:28,090 But next, we need to listen for when that occupant property gets updated. 364 00:24:28,100 --> 00:24:31,610 Because when we force the player to sit, then it's going to update this property. 365 00:24:31,610 --> 00:24:32,690 So what do we want to do? 366 00:24:32,900 --> 00:24:39,590 Well, we want to listen If the seat gets an occupant so we get a new occupant, then what we want to 367 00:24:39,590 --> 00:24:44,360 do is we want to set that variable of current occupant to the seat dot occupant. 368 00:24:45,520 --> 00:24:49,570 We want to disable the prompt so nobody else can enter the vehicle. 369 00:24:50,960 --> 00:24:55,130 And when the player enters the vehicle, we want to play the ignition sound. 370 00:24:55,220 --> 00:24:56,360 So the car is starting up. 371 00:24:56,360 --> 00:24:57,710 So we'll play that sound. 372 00:24:59,070 --> 00:25:03,570 And I don't want the car to idle right away because we have to get past that ignition. 373 00:25:03,570 --> 00:25:10,650 So I'll just wait like two seconds, because if we go to our sound here, that is inside of our body. 374 00:25:15,070 --> 00:25:17,770 We have to wait about two seconds before the car starts idling. 375 00:25:17,770 --> 00:25:18,790 So we'll wait for that. 376 00:25:20,110 --> 00:25:26,560 And then once those two seconds are up, then we can start playing the Idol sound, which is set to 377 00:25:26,560 --> 00:25:28,540 loop forever until we stop the sound. 378 00:25:28,690 --> 00:25:33,940 However, after we wait for these two seconds, there could be a chance that the player sits down and 379 00:25:33,940 --> 00:25:35,200 then immediately sits back up. 380 00:25:35,200 --> 00:25:37,810 And we don't want to play the idol sound if there's no occupant. 381 00:25:37,810 --> 00:25:44,080 So after we wait for two seconds, we still need to make sure there is a seat occupant if there isn't. 382 00:25:44,910 --> 00:25:45,920 Then we'll just return. 383 00:25:45,920 --> 00:25:47,180 We don't need to play the sound. 384 00:25:48,400 --> 00:25:50,470 So we'll do idle play. 385 00:25:51,100 --> 00:25:55,960 And then once we start playing the idling sound, that's when we need to start updating the audio for 386 00:25:55,960 --> 00:25:56,800 our idling sound. 387 00:25:56,800 --> 00:25:58,750 So that's why we'll call this function here. 388 00:25:59,650 --> 00:26:01,300 So what's this function going to do? 389 00:26:01,330 --> 00:26:04,750 Well, this function is going to loop for us. 390 00:26:04,780 --> 00:26:06,730 So while we have an occupant. 391 00:26:06,730 --> 00:26:09,100 So while seat occupant is true. 392 00:26:10,020 --> 00:26:16,860 Then what we're going to do is we're going to set the playback speed of our idle sound equal to this. 393 00:26:16,890 --> 00:26:23,430 We're going to call the math.max function and we're going to pass minimum playback speed. 394 00:26:24,820 --> 00:26:25,150 Actually. 395 00:26:25,150 --> 00:26:26,710 Why did I name it sound? 396 00:26:27,480 --> 00:26:28,320 Should be Speed. 397 00:26:29,010 --> 00:26:29,430 Minimum. 398 00:26:29,430 --> 00:26:30,180 Playback. 399 00:26:30,180 --> 00:26:30,750 Speed. 400 00:26:32,190 --> 00:26:33,900 So minimum playback speed. 401 00:26:35,040 --> 00:26:39,290 In case the second number we pass goes below the minimum playback speed. 402 00:26:39,290 --> 00:26:46,430 We're guaranteed to have a playback speed of at least 0.6 because if it goes to like 0.1 or 0 or negative 403 00:26:46,430 --> 00:26:52,400 or whatever, this gets the maximum number and this will always be the max if the second number goes 404 00:26:52,400 --> 00:26:53,060 below it. 405 00:26:53,510 --> 00:26:55,370 So what is the second number going to be? 406 00:26:55,400 --> 00:27:00,660 Well, it's going to be the minimum playback speed, but we're going to multiply it by this. 407 00:27:00,680 --> 00:27:07,400 We're going to multiply it by the cars primary part, which is the body of the car inside of the model. 408 00:27:07,400 --> 00:27:14,330 I set the primary part to be the body and this body, since it has all of this stuff attached to it. 409 00:27:14,420 --> 00:27:16,100 It's called an assembly. 410 00:27:16,610 --> 00:27:19,360 And this assembly has a velocity. 411 00:27:19,370 --> 00:27:24,710 So when it's moving, the game is like, hey, this has this has a velocity in a specific direction. 412 00:27:25,040 --> 00:27:28,730 And from that we can calculate how fast the car is moving. 413 00:27:28,850 --> 00:27:35,550 So we can get the assembly linear velocity and we can get the magnitude of this velocity. 414 00:27:35,550 --> 00:27:42,150 So it just returns to us a number that represents how far out this velocity is. 415 00:27:42,150 --> 00:27:44,130 How big is this vector? 416 00:27:44,160 --> 00:27:49,070 Because if we're only moving at like one stud per second, then this vector is going to be super tiny. 417 00:27:49,080 --> 00:27:53,190 Our magnitude is going to be small, but if we're moving at like 50 studs per second, then it's going 418 00:27:53,190 --> 00:27:56,040 to be a larger magnitude, which means we're going faster. 419 00:27:56,040 --> 00:28:00,270 And that means we have to increase the playback speed of our idling sound. 420 00:28:01,040 --> 00:28:04,610 But let's say we're we are moving 55 studs per second. 421 00:28:04,610 --> 00:28:07,310 That's going to return a value of like 55 here. 422 00:28:07,310 --> 00:28:13,160 And if we multiply 55 by our 0.6, we're going to get a playback speed of like 20 something, which 423 00:28:13,160 --> 00:28:14,320 is way too fast. 424 00:28:14,330 --> 00:28:18,680 So we need to reduce this number down a lot, but by not too much. 425 00:28:18,950 --> 00:28:24,320 And if we divide it by 20, that should give us a pretty good number for our playback speed. 426 00:28:24,350 --> 00:28:31,340 Of course you can mess with this magic number to, you know, adjust how how fast you want the playback 427 00:28:31,340 --> 00:28:33,140 speed of our audio to be while we're driving. 428 00:28:33,140 --> 00:28:34,940 But I found 20 to be pretty good. 429 00:28:36,210 --> 00:28:43,740 And of course, since we're in a while loop, we need to yield and we'll yield 4.05 seconds. 430 00:28:43,740 --> 00:28:49,710 So this will update the playback speed of our sound every 0.5 or 0.0 five seconds. 431 00:28:50,570 --> 00:28:51,020 Anyway. 432 00:28:51,020 --> 00:28:56,450 So once we've got all that done and there's a player in the seat, whenever they, you know, press 433 00:28:56,450 --> 00:29:00,020 A or D on their key, it's going to update this steer property. 434 00:29:00,020 --> 00:29:06,170 And that means we want to steer the front tires In order to steer the front tires, we need to rotate 435 00:29:06,170 --> 00:29:07,070 those attachments. 436 00:29:07,070 --> 00:29:10,400 That's in the tire because it's using that cylindrical constraint. 437 00:29:10,400 --> 00:29:14,560 If I rotate the attachment in the tire, then it'll rotate the tire itself. 438 00:29:14,570 --> 00:29:20,420 So we need to calculate an orientation and it's going to be a new vector three. 439 00:29:21,010 --> 00:29:27,790 We don't need to rotate it on the x axis, but we need to rotate it on the vertical y axis and we're 440 00:29:27,790 --> 00:29:29,490 going to rotate it by. 441 00:29:29,500 --> 00:29:38,500 We're going to get the seat dot steer, which is either going to be negative one, 1 or 0, and we're 442 00:29:38,500 --> 00:29:41,980 going to multiply it by the max tire rotation. 443 00:29:42,190 --> 00:29:46,450 So if we're not steering, it's zero, then we're not going to rotate the tire at all. 444 00:29:46,690 --> 00:29:53,140 If it's negative one, we multiply this and rotate it in the other direction, but it's actually going 445 00:29:53,140 --> 00:29:55,450 to rotate in the opposite direction. 446 00:29:55,450 --> 00:29:58,450 So if we press A, it's going to rotate to the right. 447 00:29:58,450 --> 00:30:01,510 And if we press D on our keyboard, it's going to rotate to the left. 448 00:30:01,510 --> 00:30:06,430 So I'm going to make sure to negate the posterior value. 449 00:30:07,950 --> 00:30:10,610 And then for the Z is very important. 450 00:30:10,620 --> 00:30:16,080 Remember that the attachments that are inside of our tires are actually excuse me, we're rotating, 451 00:30:16,110 --> 00:30:19,920 not the attachment on our tires, but we're actually rotating the attachment in the body. 452 00:30:20,880 --> 00:30:22,230 Let me just correct that real quick. 453 00:30:22,260 --> 00:30:26,580 We're rotating these attachments to rotate our tires and not the ones in here. 454 00:30:27,410 --> 00:30:32,990 And we need to remember that each of these attachments, we've already rotated them by 90 degrees on 455 00:30:32,990 --> 00:30:33,660 the Z axis. 456 00:30:33,660 --> 00:30:34,960 So we've got to make sure we include that. 457 00:30:34,970 --> 00:30:36,170 We don't want that to change. 458 00:30:38,010 --> 00:30:42,450 But since we've applied this orientation, that means we can rotate the tires. 459 00:30:42,450 --> 00:30:48,510 But I don't want to rotate the tires instantly and said I want them to slowly move to that position 460 00:30:48,510 --> 00:30:50,270 based on this rotation duration. 461 00:30:50,280 --> 00:30:52,230 And that's where the tween service comes in. 462 00:30:52,470 --> 00:30:54,750 So we're going to create two new tweens. 463 00:30:54,750 --> 00:31:01,260 We're going to do tween service and we're going to create a tween on what we're going to get the body 464 00:31:01,260 --> 00:31:04,770 and we're going to get the front attachment for one of the tires. 465 00:31:04,770 --> 00:31:08,760 So first we'll do front attachment for the left tire. 466 00:31:10,130 --> 00:31:12,260 We're going to create a new tween info. 467 00:31:13,100 --> 00:31:18,680 And inside there, we're just going to have the rotation duration and what do we want to tween We want 468 00:31:18,680 --> 00:31:24,740 to tween the orientation of our attachment, which is going to be equal to the orientation that we just 469 00:31:24,740 --> 00:31:25,910 created right here. 470 00:31:26,560 --> 00:31:33,070 And of course, since this create function in our tween service going to return to us a track, we can 471 00:31:33,070 --> 00:31:34,120 play it right here. 472 00:31:34,120 --> 00:31:38,770 We can just call play and we don't need to store the return from this function in a variable. 473 00:31:39,670 --> 00:31:42,310 And then we can just copy this. 474 00:31:44,050 --> 00:31:47,680 And do the exact same thing, but for the front right tyre. 475 00:31:48,510 --> 00:31:49,800 Just like that. 476 00:31:50,860 --> 00:31:53,860 So what we can do is we can test what we've got done so far. 477 00:31:53,860 --> 00:31:55,780 And if I go and play here. 478 00:31:57,450 --> 00:31:59,040 You see if I hop in my vehicle. 479 00:32:01,750 --> 00:32:04,420 We get the start ignition sound and then we get the idling sound. 480 00:32:04,420 --> 00:32:12,640 And if I press A on my keyboard, the tires tween to the left, if I let go of a they tween to be neutral, 481 00:32:12,640 --> 00:32:16,120 and if I press de they tween to the right. 482 00:32:16,120 --> 00:32:17,110 So very cool. 483 00:32:18,720 --> 00:32:21,480 Inside of this function here. 484 00:32:21,600 --> 00:32:25,290 We need to listen for when we press down on the throttle. 485 00:32:25,740 --> 00:32:32,910 So the very first thing we need to do is we need to set the torque in all of our cylindrical constraints 486 00:32:32,910 --> 00:32:35,960 to the torque that has been defined in our vehicle seat. 487 00:32:37,420 --> 00:32:38,980 And that's going to be easy. 488 00:32:39,010 --> 00:32:41,620 We just need to create a reference to that value. 489 00:32:43,000 --> 00:32:44,890 Equal to stalk. 490 00:32:45,940 --> 00:32:51,220 And then for every single one of these cylindrical constraints that we've referenced up here, we just 491 00:32:51,220 --> 00:32:52,600 need to set the torque to that. 492 00:32:52,600 --> 00:32:53,500 So. 493 00:32:54,670 --> 00:32:56,470 Cylindrical. 494 00:32:56,470 --> 00:32:56,950 Right. 495 00:32:56,950 --> 00:32:58,480 Left stalk. 496 00:32:59,300 --> 00:33:02,090 Or I believe it is motor max torque. 497 00:33:02,090 --> 00:33:03,440 We're just setting it to talk. 498 00:33:03,470 --> 00:33:06,020 Do it again for the. 499 00:33:07,570 --> 00:33:07,990 Rear. 500 00:33:08,020 --> 00:33:08,800 Right. 501 00:33:11,900 --> 00:33:12,980 Do it again. 502 00:33:16,080 --> 00:33:18,000 It looks like I misspelled that one. 503 00:33:18,840 --> 00:33:19,660 So. 504 00:33:19,710 --> 00:33:23,210 Rent, cylindrical, cylindrical. 505 00:33:23,490 --> 00:33:24,090 There we go. 506 00:33:25,340 --> 00:33:26,360 We'll fix that right here. 507 00:33:27,970 --> 00:33:31,090 And then we need to do this for the front. 508 00:33:31,090 --> 00:33:35,950 So we'll do front right motor max torque equal to torque. 509 00:33:37,200 --> 00:33:41,010 And then we need to do the last one for the front left. 510 00:33:47,530 --> 00:33:50,940 Now that we've set the torque, that means we can start to rotate our tires. 511 00:33:50,950 --> 00:33:56,610 And that means we need to calculate the correct angular velocity for the tires. 512 00:33:56,620 --> 00:33:57,880 How do we do that? 513 00:33:58,180 --> 00:33:59,410 It's going to be pretty simple. 514 00:33:59,410 --> 00:34:02,740 We can just create a variable, call it angular velocity. 515 00:34:03,600 --> 00:34:09,650 And we're going to set it equal to the seats throttle, which is either going to be negative one, 0 516 00:34:09,650 --> 00:34:10,830 or 1. 517 00:34:11,220 --> 00:34:14,490 And we just multiply it by our max angular velocity. 518 00:34:14,670 --> 00:34:19,510 So if we want to go forward, it's going to be one times the max angular velocity. 519 00:34:19,530 --> 00:34:23,460 If we're going backwards, this number will be negative and that means the tires are going to rotate 520 00:34:23,460 --> 00:34:23,970 the other way. 521 00:34:23,970 --> 00:34:25,140 So we go backwards. 522 00:34:25,380 --> 00:34:29,040 And if it's zero, then we have no angular velocity at all. 523 00:34:29,190 --> 00:34:30,160 Pretty easy. 524 00:34:30,210 --> 00:34:32,340 So then we can just copy this. 525 00:34:33,310 --> 00:34:36,020 And we're going to set it to this angular velocity. 526 00:34:36,040 --> 00:34:36,860 Copy that. 527 00:34:36,860 --> 00:34:38,440 And just paste them all here. 528 00:34:39,300 --> 00:34:41,610 And we need to set that in the. 529 00:34:42,410 --> 00:34:44,590 And your velocity property. 530 00:34:46,230 --> 00:34:50,270 Just copy that and paste it there, paste it there and paste it there. 531 00:34:50,280 --> 00:34:51,190 Very cool. 532 00:34:51,210 --> 00:34:53,730 So now if we go and play again. 533 00:34:57,920 --> 00:35:01,790 If I press a W, our tires should start rotating forwards. 534 00:35:02,360 --> 00:35:02,720 There we go. 535 00:35:02,720 --> 00:35:03,620 They're rotating forwards. 536 00:35:03,620 --> 00:35:05,180 I let go of w they stopped. 537 00:35:05,180 --> 00:35:10,370 If I press s, they rotate backwards and I release s and we're all good to go. 538 00:35:10,550 --> 00:35:11,240 Very cool. 539 00:35:11,660 --> 00:35:18,290 So the next thing we need to do is when the player jumps up out of the seat, we need to either put 540 00:35:18,290 --> 00:35:24,200 them at the position of this exit attachment at the bottom of the car or the top of the car, because 541 00:35:24,200 --> 00:35:30,110 if the car is flipped over, we need to set their position to be on this bottom attachment. 542 00:35:30,440 --> 00:35:33,200 Well, we can go back to this property here. 543 00:35:34,360 --> 00:35:35,800 And we're going to listen. 544 00:35:35,800 --> 00:35:41,800 So when this occupant property changes and there is no occupant, meaning the last player who was ever 545 00:35:41,800 --> 00:35:44,050 in the vehicle jumped out of the seat. 546 00:35:44,080 --> 00:35:48,730 What we need to do is we need to check if there was a current occupant that was last sitting in the 547 00:35:48,730 --> 00:35:50,050 car, if there was. 548 00:35:50,770 --> 00:35:55,720 Then we need to figure out which attachment we need to teleport their torso to. 549 00:35:55,870 --> 00:35:59,050 So I'll just create a variable called exit attachment. 550 00:36:00,010 --> 00:36:07,420 And then what we could do is we can check if the seat dot attachment exit top, we're going to get the 551 00:36:07,420 --> 00:36:10,270 world keyframe the position of that attachment in the world. 552 00:36:12,120 --> 00:36:13,050 And get its y axis. 553 00:36:13,050 --> 00:36:17,970 And we're going to check if this y axis is above the other attachment. 554 00:36:17,970 --> 00:36:23,700 So attachment exit bottom world C frame dot position dot y. 555 00:36:24,360 --> 00:36:30,990 So if this attachment is above our bottom attachment, meaning our car isn't flipped over. 556 00:36:32,400 --> 00:36:37,470 Then our exit attachment is just going to be equal to that attachment exit top. 557 00:36:37,530 --> 00:36:45,780 Otherwise, if it's below, then we need to set the exit attachment equal to seat dot exit attachment 558 00:36:45,780 --> 00:36:46,770 at the bottom. 559 00:36:46,770 --> 00:36:49,440 So attachment exit bottom. 560 00:36:50,430 --> 00:36:55,590 Once we do that, we can get the current occupant and we get the parent. 561 00:36:55,590 --> 00:37:00,810 Because remember, current occupant represents a humanoid and the parent of the humanoid is the player's 562 00:37:00,810 --> 00:37:01,640 character. 563 00:37:01,650 --> 00:37:07,380 And then we get the humanoid root part and the player's character, and we set the position equal to 564 00:37:07,380 --> 00:37:11,850 the exit attachment that world keyframe and get that position. 565 00:37:13,110 --> 00:37:17,150 And then once that's done, we just set current occupant to nil because there is no more occupant. 566 00:37:17,160 --> 00:37:17,910 They got out. 567 00:37:18,270 --> 00:37:22,230 We also need to reset the prompt to be enabled again because there's no one in the car anymore. 568 00:37:22,230 --> 00:37:24,810 So prompt dot enabled equals true. 569 00:37:25,470 --> 00:37:30,240 And then we need to stop the start sound and the idle sound in case they were playing. 570 00:37:30,240 --> 00:37:31,020 So start sound. 571 00:37:31,020 --> 00:37:33,240 We're going to stop an idle sound. 572 00:37:33,240 --> 00:37:36,390 We're going to stop just like that. 573 00:37:36,750 --> 00:37:38,600 And I think that's it for the car. 574 00:37:38,610 --> 00:37:46,170 So let's just go ahead and play test here just to make sure everything works as we expect and then we 575 00:37:46,170 --> 00:37:48,420 can go drive it around a little bit. 576 00:37:49,620 --> 00:37:52,290 So the car starts up idle sound. 577 00:37:52,290 --> 00:37:55,050 We can turn the tires in the correct direction. 578 00:37:55,050 --> 00:37:57,780 We can spin the tires forward backwards. 579 00:37:57,780 --> 00:38:02,190 And if we hop out, you see, we get teleported to that attachment above the car. 580 00:38:02,840 --> 00:38:07,820 However, let's say I decided to make the car upside down. 581 00:38:09,720 --> 00:38:11,250 And we'll playtest it again. 582 00:38:14,730 --> 00:38:20,620 Because this top attachments y position is going to be less than the one that is underneath the car. 583 00:38:20,640 --> 00:38:25,500 If I exit the car, we get teleported to the attachment below the car. 584 00:38:25,530 --> 00:38:26,400 Very cool. 585 00:38:27,580 --> 00:38:30,310 Let's rotate our car back to normality. 586 00:38:30,760 --> 00:38:32,860 We're going to anchor the body. 587 00:38:33,550 --> 00:38:38,080 And I've actually generated some terrain over here because we're going to test this bad boy out. 588 00:38:38,080 --> 00:38:39,910 So we're going to put our car right there. 589 00:38:39,910 --> 00:38:41,500 We're going to play right here. 590 00:38:42,960 --> 00:38:46,320 Now we're going to see if our car works as we expect. 591 00:38:47,610 --> 00:38:52,110 Of course, the physics are going to be a little weird because my processor is being taken up by the 592 00:38:52,110 --> 00:38:54,900 recording software and trying to calculate physics at the same time. 593 00:38:54,900 --> 00:39:00,960 So it might be a little wonky, but if we get in, our car starts up good and we should be able to start 594 00:39:00,960 --> 00:39:01,470 driving. 595 00:39:01,470 --> 00:39:05,460 But as you can see, we can rotate our tires and now we can drive. 596 00:39:07,000 --> 00:39:12,920 And as you can see, when our speed goes up, the idle sound gets its playback speed increased. 597 00:39:12,940 --> 00:39:13,390 Right. 598 00:39:14,580 --> 00:39:15,270 Just like that. 599 00:39:21,190 --> 00:39:25,150 And as you can see, our suspension is helping us out, making this ride a lot smoother. 600 00:39:25,150 --> 00:39:30,460 As you can see, our tires are moving up and down independently because of the spring we put in there. 601 00:39:30,460 --> 00:39:35,290 And those springs are also helped out by those cylindrical constraints that forces the tires to move 602 00:39:35,290 --> 00:39:40,570 only up and down a set amount so that the tires can only move up so much and they can only move down 603 00:39:40,570 --> 00:39:43,510 so much, just like it would be in an actual car. 604 00:39:45,760 --> 00:39:49,840 And since I have also increased the friction on the tires, we aren't sliding around that much at all. 605 00:39:52,220 --> 00:39:58,160 Now, if I were to go into the properties for these tires, these custom physical properties we set 606 00:39:58,160 --> 00:40:01,160 and let's say I reduce the friction to like 0.1. 607 00:40:01,770 --> 00:40:03,060 What do you think's going to happen? 608 00:40:03,150 --> 00:40:04,980 I say we're going to drift around all over the place. 609 00:40:04,980 --> 00:40:05,760 Let's find out. 610 00:40:06,730 --> 00:40:09,070 I don't think we're actually going to be able to grip the ground at all. 611 00:40:09,070 --> 00:40:09,430 Well. 612 00:40:10,070 --> 00:40:11,390 But if I drive around. 613 00:40:12,530 --> 00:40:12,710 Yeah. 614 00:40:12,740 --> 00:40:15,620 You can see we are drifting around. 615 00:40:16,130 --> 00:40:17,210 Watch more. 616 00:40:17,210 --> 00:40:18,800 Even though I stopped the car. 617 00:40:21,040 --> 00:40:23,460 You see, we are drifting around a lot more than before. 618 00:40:24,000 --> 00:40:28,830 But I'm going to, of course, reset that friction to be higher again. 619 00:40:28,830 --> 00:40:30,210 1.22. 620 00:40:30,210 --> 00:40:30,840 Maybe. 621 00:40:30,870 --> 00:40:32,310 Maybe we'll try out 1.5. 622 00:40:32,310 --> 00:40:33,540 Maybe that's a little better. 623 00:40:39,990 --> 00:40:42,060 As you can see, we don't drift around as much anymore. 624 00:40:42,240 --> 00:40:45,450 I mean, we pretty much stop, which is what a tire is supposed to do. 625 00:40:45,480 --> 00:40:46,380 It's made out of rubber. 626 00:40:46,410 --> 00:40:47,400 It would make sense. 627 00:40:52,710 --> 00:40:57,840 But otherwise, that's how you make a car with suspension or a simple car in Roblox. 628 00:40:58,200 --> 00:41:01,290 As you can see, it's actually not that complicated. 629 00:41:01,290 --> 00:41:06,780 You just need to have a little bit of knowledge on a couple of constraints inside of the Roblox API. 630 00:41:06,810 --> 00:41:12,780 Of course, you need to understand a little bit about angular velocity and torque on cars, but other 631 00:41:12,780 --> 00:41:18,990 than that, it only took us 89 lines of code and we've got a working car here that can turn, go forwards, 632 00:41:19,020 --> 00:41:24,690 go backwards, and if it flips upside down like this, we can hop out of the car and make it out. 633 00:41:24,810 --> 00:41:27,960 So I hope you enjoyed this lecture and I'll see you in the next one.